#ifndef _HLFS_H_
#define _HLFS_H_

#include <time.h>
#include <stdint.h>
#include "storage.h"
#include "cmd_define.h"

#define MAX_FILE_NAME_LEN 128

struct inode {
	    int64_t length;
    	int32_t uid;
    	int32_t gid;
    	int32_t mode;
    	uint64_t ctime;               /* time of last status change */
    	uint64_t mtime;               /* time of last modification */
    	uint64_t atime;               /* time of last access */
    	int64_t blocks[12];         /* the first 8KB*12=96KB */
    	int64_t iblock;             /* the next 8KB/8*8KB=8MB */
    	int64_t doubly_iblock;      /* the next 8K/8*8K/8*8K=8GB */
    	int64_t triply_iblock;      /* the next 8K/8*8K/8*8K/8*8K=8TB */
}__attribute__((packed));  

struct inode_map_entry {
	uint64_t inode_no;	        /* inode number */
    uint64_t inode_addr;		/* inode's DISK address */ 
}__attribute__((packed)); 

struct super_block {
    uint32_t seg_size;					/* max segment size */
    uint32_t block_size;		        /* max data block size */
    char fsname[MAX_FILE_NAME_LEN];		/* record the file's name */
};

//#pragma pack (4)
struct log_header {
    int32_t version;
    int64_t header_checksum;
    int64_t data_checksum;
    uint32_t log_size;
    uint64_t ctime;       /* create time */
    uint64_t start_db_no; /* log first db no*/
    uint32_t db_num;	  /* db amounts */
    uint32_t ib_num;	  /* ib amount */
    char data[0];
}__attribute__((packed)); 

#define LOG_HEADER_LENGTH sizeof(struct log_header)


struct write_req{
   char * req_buf;
   uint32_t db_start;
   uint32_t db_end;
};
struct write_rsp{
   int res;
   uint64_t size;
};

static GStaticMutex g_segfile_safe_del_mutex = G_STATIC_MUTEX_INIT;
/* The control structure in RAM */
struct hlfs_ctrl {
	struct super_block sb;	        	/* the sb in RAM */
	struct inode_map_entry imap_entry;	/* the inode map in RAM */
	struct inode inode;		
	int64_t last_segno;				/* the current segment */
	uint64_t last_offset;				/* the current offset in current segment */
    struct back_storage *storage;
	struct nbd_ops *nbd;
    void * cur_file_handler;
    GAsyncQueue * write_req_aqueue;
    GAsyncQueue * write_rsp_aqueue;
    int write_task_run;
    CTRL_REGION_T * ctrl_region;
};

struct hlfs_ctrl *
init_hlfs(const char *uri, const char *fs_name);
int deinit_hlfs(struct hlfs_ctrl *ctrl);
int hlfs_open(struct hlfs_ctrl *ctrl , int flag);
int hlfs_close(struct hlfs_ctrl *ctrl);
int hlfs_read(struct hlfs_ctrl * ctrl,char* read_buf,uint32_t read_len,uint64_t pos);
int hlfs_write(struct hlfs_ctrl * ctrl,char* write_buf,uint32_t write_len,uint64_t pos);
#endif
